QuickDraw Focus Library (FocusLib)
This section describes the utilities defined in the files FocusLib.h and FocusLib.cpp. These utilities are useful for setting up the drawing environment to render into a facet for Mac OS part editors using the classic QuickDraw imaging environment. Using QuickDraw GX is discussed in the recipe QuickDraw GX and OpenDoc.What the Focus Library Does
The term focus, as used in the focus library, is only dimly related to the regular OpenDoc concept of a focus. The term comes from theFocus
method in MacApp, which sets up QuickDraw to draw into a view.Focusing does the following things:
Once your drawing environment is focused, you can start issuing QuickDraw commands (or doing higher level things that use QuickDraw) using your frame's coordinate system.
- Makes the facet's canvas the current graphics port (
GrafPort
).- Moves the origin of the graphics port to the origin of the frame's coordinate system, based on the internal and external transformations. In other words, (0,0) to QuickDraw is now the same place as (0,0) in your frame's coordinates.
- Sets the clip region to the facet's clip shape, to prevent you from drawing outside of the facet.
What the Focus Library Does Not Do
The focus library sets up the QuickDraw environment, so it cannot set up any kind of drawing state or transformations that QuickDraw does not understand. In particular, it does not handle any type of transformations other than offsets. If your facet ends up scaled, rotated, or skewed, the focus library helps you only with the offset portion of the transformation. You can do the rest of the transformation manually by transforming the coordinates of all points before you draw them.Transformations other than scaling are particularly hard to handle in QuickDraw, which provides no native facilities for rotating text, bitmaps, or ellipses. QuickDraw GX handles all kinds of transformations automatically.
Using the Focus Library From C++
Using the focus library is easy. The usual way, for C++ clients, is to declare aCFocus
object on the stack. When the object is constructed, the focusing takes place. When the object goes out of scope and is destroyed, the previous state of QuickDraw is restored. For example:
void DrawMyStuff( Environment *ev, ODFacet *facet ) { CFocus foc(ev,facet); MoveTo(0,0); LineTo(100,100); }There are three variants ofCFocus
, described in the following sections.CFocusWindow
TheCFocusWindow
class sets the window, not the facet's canvas, as the current graphics port. There is no difference, unless your facet is on an offscreen canvas. In that case, a regularCFocus
would not cause the drawing to appear immediately on screen since it would first go into the offscreen canvas until the next update event. For interactive use such as rubber-banding a line or object while the mouse is down, useCFocusWindow
to ensure that things are drawn immediately to the screen.CFocusFrame
TheCFocusFrame
class does not take into account the frame's internal transformation. This means that (0,0) will be the top-left corner of the facet. This is useful when drawing frame adornments such as borders or scroll bars instead of the actual contents.CFocusWindowFrame
TheCFocusWindowFrame
class is a combination ofCFocusWindow
andCFocusFrame
.The constructors of any of the
CFocus
classes take an optional extra parameter, which is a pointer to anODShape
object. If it is supplied, drawing is further clipped to the intersection of that shape and the facet's clip shape. This is useful when drawing into only part of the facet (as when handling aDraw
method call).Using the Focus Library From C
If you are using C, or do not use C++ features like constructors, you can explicitly call theBeginFocus
andEndFocus
functions. For example:
void DrawMyStuff( Environment *ev, ODFacet *facet ) { FocusState state; BeginFocus(ev,&state,facet,kODTrue,kODFalse,kODNULL); MoveTo(0,0); LineTo(100,100); EndFocus(&state); // Must explicitly end focusing! }You must declare aFocusState
variable and then callBeginFocus
, whose parameters look like this:
void BeginFocus( Environment *ev, FocusState*, ODFacet*, ODBoolean toContent, ODBoolean toWindow, ODShape *clipTo );ThetoContent
parameter determines whether to clip to the frame's content (as inCFocus
) or to the frame border (as inCFocusFrame
).The
toWindow
parameter determines whether to draw directly into the window (as inCFocus
) or into the facet's canvas (as inCFocusWindow
).The
clipTo
parameter, if notkODNULL
, is anODShape
to which drawing is clipped.
- IMPORTANT
- It is important that you always call
EndFocus
afterBeginFocus
. If you don't, the drawing state is not restored and you will leak some memory. If you use exceptions, and anything betweenBeginFocus
andEndFocus
could throw an exception, you need to catch the exception and callEndFocus
before re-raising it. (The C++ classes are based on theDestructo
class, so they always clean up automatically.)![]()
PostScript Printing
The focus library takes care of some tricky situations in PostScript(TM) printing. The LaserWriter driver does not handle QuickDraw Regions, so any attempt to clip to a nonrectangular area is ignored in the PostScript output. Not being able to clip to nonrectangular areas is a problem, since facets are often clipped to nonrectangular areas.To work around this, the focus library includes two utility functions that emit some fancy PostScript code to set the clipping properly. If you are using the focus library calls described previously, these functions are called automatically and you don't need to worry about them. You need to know about these calls only if you do not want to use the rest of the focus library.
ODBeginPostScriptClip
emits PostScript code to clip to theODShape
object passed in (in the coordinate system of the current graphics port).ODEndPostScriptClip
ends the clipping. These functions will have no effect unless the current graphics port is in fact a printing port that is printing via the LaserWriter driver.
Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help